home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Applications… / Getting Started w⁄GX ƒ / Getting Started GX - printing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-20  |  10.1 KB  |  360 lines  |  [TEXT/KAHL]

  1. /**
  2.  --
  3.  --        App:        Getting Started w/QD GX (WWDC)
  4.  -- 
  5.  -- 
  6.  --        Version:    1.0     4/93:    added all of the calls required to support the "Getting 
  7.  --                                    Started with QuickDraw™ GX" session at the WWDC '93     
  8.  --
  9.  --                            8/93:    updated file to work with the ß2 "GXified" interface files
  10.  --                            3/94:    dmh - general cleanup/debugging.
  11.  -- 
  12.  --        File:        Getting Started GX - printing.c
  13.  --
  14.  --
  15.  --        Comments:    This code contains all of the functions required to print the QuickDraw GX shapes we created.
  16.  --                    We use the QuickDraw GX printing method which takes a picture and passes it to the QuickDraw GX 
  17.  --                    printing system. The picture will always contains what is in the front window.
  18.  --
  19.  --                    If QuickDraw GX printing systems has not been installed, the printing menu items in the File
  20.  --                    menu will be dis-abled.
  21.  --
  22.  --
  23.  --        Components:    Getting Started GX - main.c
  24.  --                    Getting Started GX - main.h
  25.  --                    Getting Started GX - shapes.c
  26.  --                    Getting Started GX - printing.c
  27.  --                    Getting Started GX - misc.c
  28.  --                    Getting Started QD GX.π.rsrc
  29.  --
  30.  --                    The file titled: "Getting Started GX - main.c" contains the code required to
  31.  --                    intialize and tear down the QuickDraw GX world, and the event loop.
  32.  --
  33.  --                    The file titled: "Getting Started GX - shapes.c" contains of the code used to 
  34.  --                    create and manipulate the shapes draw into the window.
  35.  --        
  36.  --        
  37.  --        QuickDraw GX
  38.  --        Libraries
  39.  --        Used:        This application uses the following QuickDraw GX library code files:
  40.  --                    "color library.c", "font library.c", "graphics debug library.c",
  41.  --                    "layout library.c", "qd library.c", "shape library.c", 
  42.  --                    "transferMode library.c", and "transform library.c". 
  43.  --        
  44.  --        
  45.  --        Notes:        1) Print this file in landscape for the best results
  46.  --                    2) If you are using THINK C v5.x, I have added THINK markers to navigate the code.
  47.  --                    3) This code was adapted from the "Banana Jr." QuickDraw GX sample.
  48.  --
  49.  --
  50.  --        Author:        Pete "Luke" Alexander
  51.  --                    Developer Technical Support
  52.  --                    AppleLink: DEVSUPPORT
  53.  --
  54.  --        
  55.  --        ©1992 - 1994  Apple Computer, Inc. 
  56.  --        All rights reserved.
  57.  --
  58.  **/
  59.  
  60. #include <GXPrinting.h>
  61. #include "GXExceptions.h"
  62. #include "memory.h"
  63. #include "Getting Started GX - main.h"
  64.  
  65.  
  66. /*------ SetUpEditMenuRec ------------------------------------------------------------------------------------*/
  67. //
  68. //    This routine sets up an gxEditMenuRecord which references our edit menu.  This structure
  69. //    is used by the GXJobDefaultFormatDialog and GXJobPrintDialog calls to allow cut, copy, & paste
  70. //    operations from the dialogs.
  71. //
  72. void SetUpEditMenuRec(gxEditMenuRecord *edMenuRec)
  73. {
  74.  
  75.     edMenuRec->editMenuID = mEdit;
  76.     edMenuRec->cutItem = iCut;
  77.     edMenuRec->copyItem = iCopy;
  78.     edMenuRec->pasteItem = iPaste;
  79.     edMenuRec->clearItem = iClear;
  80.     edMenuRec->undoItem = iUndo;
  81. }
  82.  
  83.  
  84. /*------ DoFormat ------------------------------------------------------------------------------------*/
  85. //
  86. //    This routine performs GX's equivalent of the Page Setup (PrStlDialog) call of
  87. //    the old printing architecture.
  88. //
  89. OSErr DoFormat(WindowPtr theWindow, gxDialogResult    *result)
  90. {
  91.     OSErr                err;
  92.     gxEditMenuRecord    edMenuRec;
  93.     gxJob                documentJob;
  94.  
  95.     //
  96.     //    If we have a non-nil WindowPtr, set up our edit menu record and handle the job
  97.     //    format dialog.  Remember to check for errors.
  98.     //
  99.     if (theWindow)
  100.     {
  101.         documentJob = GetDocJob(theWindow);
  102.         SetUpEditMenuRec(&edMenuRec);
  103.         *result = GXJobDefaultFormatDialog(documentJob, &edMenuRec);
  104.     }
  105.     
  106.     return GXGetJobError(documentJob);
  107. }
  108.  
  109.  
  110. /*------ DoPrinting ----------------------------------------------------------------------------------*/
  111. //
  112. //    This routine performs QuickDraw GX's equivalent of the Print gxJob Dialog (PrJobDialog) call of
  113. //    the old printing architecture, and then prints the document if the user wants to.
  114. //
  115. OSErr DoPrinting(WindowPtr theWindow)
  116. {
  117.     OSErr                err = noErr;
  118.     gxDialogResult        result;
  119.     gxEditMenuRecord    edMenuRec;
  120.     gxJob                docJob;
  121.  
  122.  
  123.     //
  124.     //    If we have a non-nil WindowPtr, set up our edit menu record and handle the print
  125.     //    job dialog.  Remember to check for errors.  If no errors occur, and the user clicks
  126.     //  ok, print the window's document.
  127.     //
  128.     if (theWindow)
  129.     {
  130.         docJob = GetDocJob(theWindow);
  131.         
  132.         SetUpEditMenuRec(&edMenuRec);
  133.         result = GXJobPrintDialog(docJob, &edMenuRec);
  134.         err = GXGetJobError(docJob);
  135.                 
  136.         if ((result == gxOKSelected) && !(err))
  137.             err = DoPrintLoop(theWindow);
  138.     }
  139.     
  140.     return err;
  141. }
  142.  
  143.  
  144.  
  145. /*------ DoPrintLoop ----------------------------------------------------------------------------------*/
  146. //
  147. //    This routine prints one copy of the window's document using whatever job and format
  148. //    is currently attached to it.  (If the window wwere just created and then the user
  149. //    selected Print One Copy w/o first selecting Page Setup…, the system default job and
  150. //    format are stored with this document.
  151. //
  152. OSErr DoPrintLoop(WindowPtr theWindow)
  153. {
  154.     OSErr        err = noErr;
  155.     gxJob        documentJob;
  156.     Str255        windowTitle;
  157.  
  158.     //
  159.     //    If we have a non-nil WindowPtr, start the print job, print a page and then finish
  160.     //    the job.  Since we have just a one page document, we don't bother counting pages.
  161.     //    Remember to check those errors!
  162.     //
  163.     if (theWindow)
  164.     {
  165.         documentJob = GetDocJob(theWindow);
  166.         GetWTitle(theWindow, windowTitle);
  167.     
  168.         GXStartJob(documentJob, windowTitle, 1);
  169.         err = GXGetJobError(documentJob);
  170.         
  171.         if (!err)
  172.         {
  173.               GXPrintPage(documentJob, 1,GXGetJobFormat(documentJob, 1), GetDocShape(theWindow));
  174.             err = GXGetJobError(documentJob);
  175.         }
  176.         
  177.         GXFinishJob(documentJob);
  178.         if (!err) err = GXGetJobError(documentJob);
  179.     }
  180.     return err;
  181. }
  182.  
  183.  
  184.  
  185. /*******************************************************************
  186.     DoPrintOneCopy sets up our job collection items for printing
  187.     one copy of a document, and then prints the document.
  188.     
  189. ********************************************************************/
  190.  
  191. OSErr DoPrintOneCopy(WindowPtr wind)
  192. {
  193.     OSErr                    err;
  194.     Collection                jobCollection;
  195.     gxCopiesInfo            copiesInfo;
  196.     gxFileDestinationInfo    destInfo;
  197.     gxPageRangeInfo            pageRangeInfo;
  198.     Ptr                        oldCopiesInfo = nil, oldPageRangeInfo = nil, oldDestInfo = nil;
  199.     long                    oldCopiesSize, oldPageRangeInfoSize, oldDestInfoSize;
  200.     TH_Doc                    doc = (TH_Doc) GetWRefCon(wind);
  201.  
  202. /* Get the job collection and set it up to print one copy…    */
  203.  
  204.     jobCollection = GXGetJobCollection(GetDocJob(wind));
  205.  
  206.  
  207. /* Set number of copies to 1.            */
  208.     
  209.     copiesInfo.copies = 1;
  210.     err = MyReplaceCollectionItem(&copiesInfo, sizeof(gxCopiesInfo),
  211.                                     gxCopiesTag, gxPrintingTagID,
  212.                                     jobCollection, &oldCopiesInfo, &oldCopiesSize);
  213.     nrequire(err, ReplaceCopies_error);
  214.  
  215.  
  216. /* Set page range to "all".    */
  217.     
  218.     pageRangeInfo.simpleRange.optionChosen = gxDefaultPageRange;
  219.     pageRangeInfo.minFromPage = 1;
  220.     pageRangeInfo.simpleRange.fromPage = 1;        // This app only handles one page docs.
  221.     pageRangeInfo.maxToPage = 1;
  222.     pageRangeInfo.simpleRange.toPage = 1;
  223.     pageRangeInfo.simpleRange.printAll = true;
  224.     err = MyReplaceCollectionItem(&pageRangeInfo, sizeof(gxPageRangeInfo),
  225.                                     gxPageRangeTag, gxPrintingTagID,
  226.                                     jobCollection, &oldPageRangeInfo, &oldPageRangeInfoSize);
  227.     nrequire(err, ReplacePageRange_error);
  228.  
  229.  
  230. /* Set destination to "printer".        */
  231.  
  232.     destInfo.toFile = false;
  233.     err = MyReplaceCollectionItem(&destInfo, sizeof(gxFileDestinationInfo),
  234.                                   gxFileDestinationTag, gxPrintingTagID,
  235.                                   jobCollection, &oldDestInfo, &oldDestInfoSize);
  236.     nrequire(err, ReplaceDestination_error);
  237.  
  238.  
  239. /* Print one copy of our document.        */
  240.  
  241.     err = DoPrintLoop(wind);
  242.  
  243.  
  244. /*    Restore original number of copies, page range, and output
  245.     destination in case anybody uses that info. */
  246.  
  247. ReplaceCopies_error:
  248.     MyReplaceCollectionItem(oldCopiesInfo, oldCopiesSize,
  249.                               gxCopiesTag, gxPrintingTagID,
  250.                             jobCollection, nil, nil);
  251.  
  252. ReplacePageRange_error:
  253.     MyReplaceCollectionItem(oldPageRangeInfo, oldPageRangeInfoSize,
  254.                             gxPageRangeTag, gxPrintingTagID,
  255.                             jobCollection, nil, nil);
  256.  
  257. ReplaceDestination_error:
  258.     MyReplaceCollectionItem(oldDestInfo, oldDestInfoSize,
  259.                             gxFileDestinationTag, gxPrintingTagID,
  260.                             jobCollection, nil, nil);
  261.  
  262.  
  263. /* Dispose of the pointers that MyReplaceCollectionItem created. */
  264.  
  265.     if (oldCopiesInfo)
  266.         DisposePtr(oldCopiesInfo);
  267.  
  268.     if (oldPageRangeInfo)
  269.         DisposePtr(oldPageRangeInfo);
  270.  
  271.     if (oldDestInfo)
  272.         DisposePtr(oldDestInfo);
  273.  
  274.     return err;
  275. }
  276.  
  277.  
  278.  
  279. /*******************************************************************
  280.     MyReplaceCollectionItem is a generic routine that replaces a
  281.     collection item with the passed data.  If the oldData parameter
  282.     is not nil, this routine creates a pointer and returns the data
  283.     that's being replaced in it.  (If the item doesn't already exist,
  284.     then a copy of the newData is returned instead.)
  285.     
  286. ********************************************************************/
  287.  
  288. OSErr MyReplaceCollectionItem(void *newData, long collectSize,
  289.                               OSType collectType, long collectID,
  290.                               Collection whichCollection,
  291.                               Ptr *oldData, long *oldDataSize)
  292. {
  293.     OSErr    err = noErr;
  294.     long    index;
  295.  
  296. /*
  297.     If we're supposed to return the old data, get it.
  298.     If there is no old data, return a copy of the new data.
  299. */
  300.  
  301.     if (oldData)
  302.     {
  303.         err = GetCollectionItemInfo(whichCollection,
  304.                                     collectType,
  305.                                     collectID,
  306.                                     dontWantIndex,
  307.                                     oldDataSize,
  308.                                     dontWantAttributes);
  309.  
  310.         if (err)
  311.         {
  312.             *oldDataSize = collectSize;
  313.             *oldData = NewPtrSys(*oldDataSize);
  314.             if (!(err = MemError()))
  315.                 BlockMove(newData, *oldData, collectSize);
  316.         }
  317.         else
  318.         {
  319.             *oldData = NewPtrSys(*oldDataSize);
  320.             if (!(err = MemError()))
  321.                 err = GetCollectionItem(whichCollection,
  322.                                         collectType,
  323.                                         collectID,
  324.                                         dontWantSize,
  325.                                         *oldData);
  326.         }
  327.     }
  328.  
  329.     nrequire(err, CouldNotSetOldData);
  330.  
  331.  
  332. // If we're adding a new collection item, do so.  Otherwise, get the
  333. // existing item's index and replace the old collection item.
  334.  
  335.     err = AddCollectionItem(whichCollection,
  336.                             collectType,
  337.                             collectID,
  338.                             collectSize,
  339.                             newData);
  340.  
  341.     if (err == collectionItemLockedErr)
  342.     {
  343.         err = GetCollectionItemInfo(whichCollection,
  344.                                     collectType,
  345.                                     collectID,
  346.                                     &index,
  347.                                     dontWantSize,
  348.                                     dontWantAttributes);
  349.         if (!err)
  350.             err = ReplaceIndexedCollectionItem(whichCollection,
  351.                                                index,
  352.                                                collectSize,
  353.                                                newData);
  354.     }
  355.  
  356. CouldNotSetOldData:
  357.     return err;
  358. }
  359.  
  360.